package io.shuttle.mbe.api

import io.shuttle.mbe.api.annotation.ChromeMinVersion
import io.shuttle.mbe.api.annotation.LowerEqMV3
import io.shuttle.mbe.api.types.Value1Function
import io.shuttle.mbe.api.types.VoidFunction
import io.shuttle.mbe.core.Promise


////////////////////
// ReadingList
////////////////////
/**
 * Use the `Browser.readingList` API to read from and modify the items in the Reading List.
 *
 * Permissions: "readingList"
 * @since Chrome 120, MV3
 */
interface ReadingList {
    /**
     * Adds an entry to the reading list if it does not exist.
     * @since Chrome 120, MV3
     * @param entry The entry to add to the reading list.
     * @param callback
     */
    @ChromeMinVersion(120)
    @LowerEqMV3
    fun addEntry(entryOptions: AddEntryOptions, callback: VoidFunction? = null): Promise<Void>

    /**
     * Retrieves all entries that match the `QueryInfo` properties. Properties that are not provided will not be matched.
     * @since Chrome 120, MV3
     * @param info The properties to search for.
     * @param callback
     */
    @ChromeMinVersion(120)
    @LowerEqMV3
    fun query(
        info: QueryInfo,
        callback: Value1Function<List<ReadingListEntry>>? = null
    ): Promise<List<ReadingListEntry>>

    /**
     * Removes an entry from the reading list if it exists.
     * @since Chrome 120, MV3
     * @param info The entry to remove from the reading list.
     * @param callback
     */
    @ChromeMinVersion(120)
    @LowerEqMV3
    fun removeEntry(info: RemoveOptions, callback: VoidFunction? = null): Promise<Void>

    /**
     * Updates a reading list entry if it exists.
     * @since Chrome 120, MV3
     * @param info The entry to update.
     * @param callback
     */
    @ChromeMinVersion(120)
    @LowerEqMV3
    fun updateEntry(info: UpdateEntryOptions, callback: VoidFunction? = null): Promise<Void>

    /**
     * Triggered when a ReadingListEntry is added to the reading list.
     * @since Chrome 120, MV3
     */
    @ChromeMinVersion(120)
    @LowerEqMV3
    var onEntryAdded: Events.Event<Value1Function<ReadingListEntry>>

    /**
     * Triggered when a ReadingListEntry is removed from the reading list.
     * @since Chrome 120, MV3
     */
    @ChromeMinVersion(120)
    @LowerEqMV3
    var onEntryRemoved: Events.Event<Value1Function<ReadingListEntry>>

    /**
     * Triggered when a ReadingListEntry is updated in the reading list.
     * @since Chrome 120, MV3
     */
    @ChromeMinVersion(120)
    @LowerEqMV3
    var onEntryUpdated: Events.Event<Value1Function<ReadingListEntry>>

    data class AddEntryOptions(
        /** Will be `true` if the entry has been read. */
        var hasBeenRead: Boolean,
        /** The title of the entry. */
        var title: String,
        /** The url of the entry. */
        var url: String,
    )

    data class QueryInfo(
        /** Indicates whether to search for read (`true`) or unread (`false`) items. */
        var hasBeenRead: Boolean?,
        /** A title to search for. */
        var title: String?,
        /** A url to search for. */
        var url: String?,
    )

    data class ReadingListEntry(
        /** The time the entry was created. Recorded in milliseconds since Jan 1, 1970. */
        var creationTime: Number,
        /** Will be `true` if the entry has been read. */
        var hasBeenRead: Boolean,
        /** The last time the entry was updated. This value is in milliseconds since Jan 1, 1970. */
        var lastUpdateTime: Number,
        /** The title of the entry. */
        var title: String,
        /** The url of the entry. */
        var url: String,
    )

    data class RemoveOptions(
        /** The url to remove. */
        var url: String
    )

    data class UpdateEntryOptions(
        /** The updated read status. The existing status remains if a value isn't provided. */
        var hasBeenRead: Boolean?,
        /** The new title. The existing tile remains if a value isn't provided. */
        var title: String?,
        /** The url that will be updated. */
        var url: String
    )
}